home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1993 / MacHack 1993.toast / MacHack™ 1987-1992 / MacHack™ '90 / Utilities ƒ / MPW Tools ƒ / MakeMake / Source / Parse.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-08-13  |  5.5 KB  |  288 lines  |  [TEXT/MPS ]

  1. # include "defs.h"
  2. # include <CType.h>
  3.  
  4. /*
  5.  * Gobble Rez statements from the input until end of file or until
  6.  * a statement beginning with "INCLUDE" or "READ" is found.  Return the
  7.  * filename from INCLUDE and READ statements; return NULL at end-of-file.
  8.  *
  9.  * Always consume an entire Rez statement, no matter what the statement is.
  10.  */
  11. char *Rparse (f)
  12. FILE *f;
  13.     {
  14.     char *s;                    /* For the return from getword()    */
  15.     static char buf[LINELEN];    /* For filenames                    */
  16.     extern char *getword ();
  17.     extern char *readfname ();
  18.     
  19.     while ((s = getword (f)) != NULL)
  20.         {
  21.         if (strcmp (s, "INCLUDE") == 0)
  22.             {
  23.             /* Filename is next word */
  24.             s = readfname (f);
  25.             if (s == NULL)
  26.                 return (NULL);
  27.             strncpy (buf, s, LINELEN);
  28.             while ((s = getword (f)) != NULL && strcmp (s, ";") != 0)
  29.                 ;
  30.             return (buf);
  31.             }
  32.         else if (strcmp (s, "READ") == 0)
  33.             {
  34.             /* Filename is word just before ";" */
  35.             while ((s = readfname (f)) != NULL && strcmp (s, ";") != 0)
  36.                 {
  37.                 strncpy (buf, s, LINELEN);
  38.                 }
  39.             if (s == NULL)
  40.                 return (NULL);
  41.             else
  42.                 return (buf);
  43.             }
  44.         while ((s = getword (f)) != NULL && strcmp (s, ";") != 0)
  45.             ;
  46.         }
  47.     return (NULL);
  48.     }
  49.  
  50. char *Pparse (in_uses, dollar_u, f)
  51. bool *in_uses;
  52. bool *dollar_u;
  53. FILE *f;        /* Input file */
  54.     {
  55.     char *s;        /* For return from getword() */
  56.     extern char *do_uses ();
  57.     extern char *getword ();
  58.     
  59.     if (*in_uses)
  60.         {
  61.         s = do_uses (dollar_u, f);
  62.         if (s == NULL)
  63.             *in_uses = FALSE;    /* Not necessarily end-of-file */
  64.         else
  65.             return (s);
  66.         }
  67.         
  68.     while ((s = getword (f)) != NULL)
  69.         {
  70.         if (strcmp (s, "{$I") == 0 || strcmp (s, "(*$I") == 0)
  71.             {
  72.             return (readfname (f));
  73.             }
  74.         else if (strcmp (s, "USES") == 0)
  75.             {
  76.             *in_uses = TRUE;
  77.             s = do_uses (dollar_u, f);
  78.             if (s == NULL)
  79.                 *in_uses = FALSE;    /* Not necessarily end-of-file */
  80.             else
  81.                 return (s);
  82.             }
  83.         }
  84.     return (NULL);
  85.     }
  86.  
  87. /*
  88.  * Return filenames, ignore commas, return NULL at end-of-file or semicolon.
  89.  */
  90. char *do_uses (dollar_u, f)
  91. bool *dollar_u;
  92. FILE *f;
  93.     {
  94.     char *s;
  95.     extern char *getword ();
  96.     extern char *readfname ();
  97.     
  98.     while (!(*dollar_u))
  99.         {
  100.         if ((s = readfname (f)) != NULL)    /* A filename */
  101.             {
  102.             strncat (s, ".p", LINELEN);
  103.             return (s);
  104.             }
  105.         if ((s = getword (f)) == NULL)        /* End of file*/
  106.             return (NULL);
  107.         if (*s == ';')                        /* End of USES clause */
  108.             return (NULL);
  109.         if (strcmp (s, "{$U") == 0 || strcmp (s, "(*$U") == 0)    /* $U */
  110.             {
  111.             *dollar_u = TRUE;
  112.             return (readfname (f));
  113.             }
  114.         if (strcmp (s, "{$I") == 0 || strcmp (s, "(*$I") == 0)
  115.             return (readfname (f));
  116.         /*
  117.          * Else it's a comma or ordinary comment or something
  118.          * ignorable; loop back for more.
  119.          */
  120.         }
  121.         
  122.     while (TRUE)
  123.         {
  124.         if ((s = getword (f)) == NULL)        /* End of file*/
  125.             {
  126.             *dollar_u = FALSE;
  127.             return (NULL);
  128.             }
  129.         if (*s == ';')                        /* End of USES clause */
  130.             {
  131.             *dollar_u = FALSE;
  132.             return (NULL);
  133.             }
  134.         if (strcmp (s, "{$U") == 0 || strcmp (s, "(*$U") == 0)    /* $U */
  135.             return (readfname (f));
  136.         if (strcmp (s, "{$I") == 0 || strcmp (s, "(*$I") == 0)
  137.             return (readfname (f));
  138.         /*
  139.          * Else it's a comma or unit name or ordinary comment or something
  140.          * ignorable; loop back for more.
  141.          */
  142.         }
  143.     }
  144.  
  145. /*
  146.  * Getword -- a general-purpose tokenizer.  Returns the next word from
  147.  * the input.  Very naive: punctuation is always a single-character token,
  148.  * except for Pascal strings (*$I {$I (*$U {$U ;
  149.  * alphanumberic strings are always single tokens; all else is ignored.
  150.  */
  151. char *getword (f)
  152. FILE *f;            /* The input */
  153.     {
  154.     int c;
  155.     int i = 0;
  156.     static char buf[LINELEN];
  157.     
  158.     while ((c = getc (f)) != EOF && !isalnum (c) && !ispunct (c))
  159.         ;
  160.     
  161.     if (ispunct (c))
  162.         {
  163.         buf[i++] = c;
  164.         if (c == '(')    /* Ugly code to recognize "(*$I" and "(*$U" */
  165.             {
  166.             c = getc (f);
  167.             if (c == '*')
  168.                 {
  169.                 buf[i++] = c;
  170.                 c = getc (f);
  171.                 if (c == '$')
  172.                     {
  173.                     buf[i++] = c;
  174.                     c = getc (f);
  175.                     if (c == 'I'|| c == 'U')
  176.                         buf[i++] = c;
  177.                     else
  178.                         {
  179.                         ungetc (c, f);
  180.                         gobbletill ("*)", f);
  181.                         }
  182.                     }
  183.                 else
  184.                     {
  185.                     ungetc (c, f);
  186.                     gobbletill ("*)", f);
  187.                     }
  188.                 }
  189.             else
  190.                 ungetc (c, f);
  191.             }
  192.         else if (c == '{')    /* Ugly code to recognize "{$I" and "{$U" */
  193.             {
  194.             c = getc (f);
  195.             if (c == '$')
  196.                 {
  197.                 buf[i++] = c;
  198.                 c = getc (f);
  199.                 if (c == 'I' || c == 'U')
  200.                     buf[i++] = c;
  201.                 else
  202.                     {
  203.                     ungetc (c, f);
  204.                     gobbletill ("}", f);
  205.                     }
  206.                 }
  207.             else
  208.                 {
  209.                 ungetc (c, f);
  210.                 gobbletill ("}", f);
  211.                 }
  212.             }
  213.         buf[i] = EOS;
  214.         }
  215.     else if (c != EOF)
  216.         {
  217.         while (i < (LINELEN - 1) && isalnum (c))
  218.             {
  219.             buf[i++] = c;
  220.             c = getc (f);
  221.             }
  222.         buf[i] = EOS;
  223.         if (c != EOF)
  224.             ungetc (c, f);
  225.         }
  226.  
  227.     if (i == 0)
  228.         return (NULL);
  229.     return (buf);
  230.     }
  231.  
  232. /*
  233.  * readfname -- return a filename terminated by whitespace,
  234.  * semicolon, comma, asterisk, or curly braces.  Take care that it
  235.  * doesn't begin with { or ( or ,
  236.  */
  237. char *readfname (f)
  238. FILE *f;            /* The input */
  239.     {
  240.     int c;
  241.     int i = 0;
  242.     static char buf[LINELEN];
  243.     
  244.     while ((c = getc (f)) != EOF && !isalnum (c) && !ispunct (c))
  245.         ;
  246.     
  247.     if (c != EOF && c != '{' && c != '}' && c != '('
  248.      && c != '*' && c != ',' && c != ';')
  249.         {
  250.         do
  251.             {
  252.             buf[i++] = c;
  253.             c = getc (f);
  254.             } while (i < (LINELEN - 1)
  255.               && (c != EOF) && !isspace (c) && (c != ',')
  256.                 && (c != ';') && (c != '{') && (c != '}') && (c != '*'));
  257.         buf[i] = EOS;
  258.         if (c != EOF)
  259.             ungetc (c, f);
  260.         }
  261.     else if (c != EOF)
  262.         ungetc (c, f);
  263.  
  264.     if (i == 0)
  265.         return (NULL);
  266.     return (buf);
  267.     }
  268.  
  269. gobbletill (end, f)
  270. char *end;
  271. FILE *f;
  272.     {
  273.     char c;
  274.     int i = 0;
  275.     
  276.     do
  277.         {
  278.         c = getc (f);
  279.         if (c == EOF)
  280.             return;
  281.         else if (c == end[i])
  282.             i++;
  283.         else if (c == end[0])
  284.             i = 1;
  285.         else
  286.             i = 0;
  287.         } while (end[i] != EOS);
  288.     }